﻿using LaserAutoTest.Common;
using SqlSugar;
using System.Text;
using Microsoft.Extensions.Logging;
using LaserAutoTest.Application.Models.PortModels;

namespace LaserAutoTest.Application
{
    public class TcpService : ITcpService
    {
        private readonly ILogger _logger;
        public TcpService(ILogger logger)
        {
            _logger = logger;
        }

        public async Task SendData()
        {
            var list = GlobalValues.Ports.ToList();
            foreach (var port in list)
            {
                string ip = port.Value.IpAddress;
                if (await IsClient(ip))
                {
                    var model = port.Value;
                    var time = DateTime.Now;
                    if (model.Command != null && model.Command.Count > 0)
                    {
                        await SendCommand(model, time);
                    }
                    await TestSignal(model, time);
                }
            }
        }

        public async Task ReceiveData(SocketBase socketBase)
        {
            try
            {
                if (socketBase.Ip != null)
                {
                    string ip = socketBase.Ip.ToString();
                    if (GlobalValues.Ports.Keys.Contains(ip))
                    {
                        if ((socketBase.Ex != null && socketBase.ClientDispose) || socketBase.Offset == 0)
                        {
                            GlobalValues.Ports[ip].IsConnected = false;
                        }
                        else
                        {
                            await ReceiveData(socketBase, ip);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
            }
        }


        #region send

        private async Task<bool> IsClient(string ip)
        {
            bool isClient = false;
            await Task.Run(() =>
            {
                isClient = GlobalValues.TcpServer.ClientList.FirstOrDefault(t => t.Ip.ToString() == ip) != null;

            });
            return isClient;
        }
        private async Task SendCommand(PortModel model, DateTime time)
        {
            await Task.Run(() => 
            {
                var command = model.Command[model.CmdIndex];
                double timeDuration = model.LastCommandTime.GetTimeDuration(DateTime.Now, command.TimeUnit);//判断延时是否到

                if (timeDuration >= command.TimeDelay)
                {
                    if (command.IsSend == false)
                    {
                        model.LastCommandTime = time;

                        if (model.CmdIndex == 0)
                        {
                            _logger.LogDebug("");
                            _logger.LogDebug("-------------------------------------------------------------------------------------------------------------------");
                            _logger.LogDebug("");
                        }
                        //显示完成
                        _logger.LogDebug(command.CommandName + "步骤完成");
                        command.IsSend = true;
                        _logger.LogDebug(command.DestinationIP + command.CommandName);
                        GlobalValues.TcpServer.SendToClient(command.DestinationIP, command.CommandName);
                    }
                }
            });
        }
        private async Task TestSignal(PortModel model, DateTime time)
        {
            await Task.Run(() =>
            {
                double Lastinterval = model.LastSendTime.GetTimeDurationSeconds(time);//判断5秒内没有通信发送探测信号

                if (Lastinterval > 5)
                {
                    model.LastSendTime = DateTime.Now;
                    GlobalValues.TcpServer.SendToClient(model.IpAddress.ToIPEndPoint(), "RFS");
                }
            });
        }

        #endregion

        #region receive
        private async Task ReceiveData(SocketBase socketBase, string ip)
        {
            await Task.Run(() =>
            {
                byte[] buffer;
                string revData = string.Empty;
                string[] strRev;
                var model = GlobalValues.Ports[ip];

                buffer = new byte[socketBase.Offset - 2];
                Array.Copy(socketBase.RecBuffer, buffer, socketBase.Offset - 2);
                revData = Encoding.UTF8.GetString(buffer);
                strRev = revData.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);

                model.IsConnected = true;
                _logger.LogDebug($"{ip}:返回数据:{revData}");

                if (model.Command != null && model.Command.Count > 0)
                {
                    var command = model.Command[model.CmdIndex];
                    command.IsReceive = true;
                    if (model.CmdIndex < model.Command.Count - 1)
                    {
                        model.CmdIndex++;
                    }
                    else
                    {
                        model.Command = null;
                        model.CmdIndex = 0;
                    }

                }
            });
        }

        #endregion
    }
}
